package xin.sparrow.util;

import org.apache.commons.lang3.time.DateUtils;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * @author wancheng  on 2019/1/5.
 */
public class CalendarUtil {

    private static final Integer MONTH_SPRING = 3;
    private static final Integer MONTH_SUMMER = 6;
    private static final Integer MONTH_AUTUMN = 9;
    private static final Integer MONTH_WINTER = 12;
    /**
     * 周一至周日对应的值
     */
    private static final Integer WEEKDAY_MONDAY = 1;
    private static final Integer WEEKDAY_TUESDAY = 2;
    private static final Integer WEEKDAY_WEDNESDAY = 3;
    private static final Integer WEEKDAY_THURSDAY = 4;
    private static final Integer WEEKDAY_FRIDAY = 5;
    private static final Integer WEEKDAY_SATURDAY = 6;
    private static final Integer WEEKDAY_SUNDAY = 7;
    /**
     * 周一至周日对应的值
     */
    private static final String MONDAY = "MONDAY";
    private static final String TUESDAY = "TUESDAY";
    private static final String WEDNESDAY = "WEDNESDAY";
    private static final String THURSDAY = "THURSDAY";
    private static final String FRIDAY = "FRIDAY";
    private static final String SATURDAY = "SATURDAY";
    private static final String SUNDAY = "SUNDAY";

    /**
     * 获取Calendar实例
     *
     * @return
     */
    public static Calendar getCalendar(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar;
    }

    /**
     * 获取年
     *
     * @return
     */
    public static Integer getYear(Date date) {
        if (date == null) {
            return null;
        }
        return getCalendar(date).get(Calendar.YEAR);
    }

    /**
     * 获取月
     *
     * @return
     */
    public static Integer getMonth(Date date) {
        return getCalendar(date).get(Calendar.MONDAY) + 1;
    }

    /**
     * 获取日
     *
     * @return
     */
    public static Integer getDay(Date date) {
        return getCalendar(date).get(Calendar.DAY_OF_MONTH);
    }

    /**
     * 是否是春季
     *
     * @param date
     * @return
     */
    public static Boolean ifSpring(Date date) {
        Integer month = getMonth(date);
        return month <= MONTH_SPRING;
    }

    /**
     * 是否是夏季
     *
     * @param date
     * @return
     */
    public static Boolean ifSummer(Date date) {
        Integer month = getMonth(date);
        return MONTH_SPRING < month && month <= MONTH_SUMMER;
    }

    /**
     * 是否是秋季
     *
     * @param date
     * @return
     */
    public static Boolean ifAutumn(Date date) {
        Integer month = getMonth(date);
        return MONTH_SUMMER < month && month <= MONTH_AUTUMN;
    }

    /**
     * 是否是冬季
     *
     * @param date
     * @return
     */
    public static Boolean ifWinter(Date date) {
        Integer month = getMonth(date);
        return MONTH_AUTUMN < month && month <= MONTH_WINTER;
    }

    /**
     * 获取2个日期之间的时间
     *
     * @param before
     * @param after
     * @return
     */
    public static List<Date> getBetween(Date before, Date after) {
        Date beforeTime = DateUtils.truncate(before, Calendar.DAY_OF_MONTH);
        Date endTime = DateUtils.truncate(after, Calendar.DAY_OF_MONTH);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(beforeTime);
        List<Date> res = new ArrayList<Date>();
        while (calendar.getTime().getTime() <= endTime.getTime()) {
            res.add(calendar.getTime());
            calendar.add(Calendar.DAY_OF_MONTH, 1);
        }
        return res;
    }

    public static Date getWeekDay(Date date, Integer weekDay) {
        Calendar calendar = getCalendar(date);
        // 获得当前日期是一个星期的第几天
        int dayWeek = calendar.get(Calendar.DAY_OF_WEEK);
        if (1 == dayWeek) {
            calendar.add(Calendar.DAY_OF_MONTH, -1);
        }
        // 设置一个星期的第一天，按中国的习惯一个星期的第一天是星期一
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        // 获得当前日期是一个星期的第几天
        int day = calendar.get(Calendar.DAY_OF_WEEK);
        int first = calendar.getFirstDayOfWeek();
        // 计算周五的日期
        calendar.add(Calendar.DAY_OF_WEEK, first - day + weekDay - 1);
        return calendar.getTime();
    }

    public static Integer getWeek(Date date) {
        Calendar calendar = getCalendar(date);
        // 获得当前日期是一个星期的第几天
        int dayWeek = calendar.get(Calendar.DAY_OF_WEEK) - 1;
        if (0 == dayWeek) {
            dayWeek = 7;
        }
        return dayWeek;
    }

    /**
     * date2比date1多的天数
     *
     * @param date1
     * @param date2
     * @return
     */
    public static int differentDays(Date date1, Date date2) {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(date1);
        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(date2);
        int day1 = cal1.get(Calendar.DAY_OF_YEAR);
        int day2 = cal2.get(Calendar.DAY_OF_YEAR);
        int year1 = cal1.get(Calendar.YEAR);
        int year2 = cal2.get(Calendar.YEAR);
        if (year1 != year2) { //同一年
            int timeDistance = 0;
            for (int i = year1; i < year2; i++) {
                if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0) {   //闰年
                    timeDistance += 366;
                } else {    //不是闰年
                    timeDistance += 365;
                }
            }
            return timeDistance + (day2 - day1);
        } else {   //不同年
            return day2 - day1;
        }
    }

    /**
     * 通过时间秒毫秒数判断两个时间的间隔
     *
     * @param date1
     * @param date2
     * @return
     */
    public static int differentDaysByMillisecond(Date date1, Date date2) {
        return (int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24));
    }

    /**
     * 获取当周周二的时间
     *
     * @param date
     * @return
     */
    public static Date getTuesday(Date date) {
        return getWeekDay(date, WEEKDAY_TUESDAY);
    }

    public static void main(String[] args) {
        System.out.println(CalendarUtil.getWeek(new Date()));
    }
}
